///@file PCExpansion.cpp
///@brief Implementation of a polynomial chaos expansion
///@author Arnaud Duval
///@version 0.0
///@date 2010/05/10

#include <fstream>
#include <string>
#include "PCExpansion.h"

///@brief Default constructor
PCExpansion::PCExpansion()
{

}

///@brief Constructor with arguments
///@param M Number of variables
///@param types Type of the variables
///@param Da Vctor of PC coefficients
///@param set IndexSet adopted to build the PCbasis
PCExpansion::PCExpansion(unsigned int M, std::string* types, Vector Da, IndexSet set)
{
	a = Da;
	basis = PCbasis(set, types);
}

///@brief Constructor from a file
///@param filename Name of the file to read
PCExpansion::PCExpansion(std::string filename)
{
	std::ifstream f(filename.c_str());
	unsigned int M;
	f >> M;
	std::string* types = new std::string[M];
	for(unsigned int i = 0 ; i < M ; i++)
		f >> types[i];
	unsigned int card;
	f >> card;
	a = Vector(card);
	for(unsigned int i = 1 ; i <= card ; i++)
		f >> a[i];
	f >> card;
	IndexSet idx(card);
	for(unsigned int i = 0 ; i < card ; i++)
	{
		MultiIndex m(M);
		for(unsigned int j = 1 ; j <= M ; j++)
			f >> m[j];
		idx[i] = m;
	}
	//Creation of PC basis
	basis = PCbasis(idx, types);
}

///@brief Destructor
PCExpansion::~PCExpansion()
{

}

///@brief Evaluate the PC expansion for a given set of parameters
///@param x Value of the parameters for which the meta-model should be evaluated
double PCExpansion::Evaluate(Vector x)
{
	return a|basis.Evaluate(x);
}

///@brief Overload of << operator
///@param s out stream
///@param p PCExpansion object to put in the out stream
std::ostream& operator << (std::ostream& s, const PCExpansion &p)
{
	s << "a : \n" << p.a << "\n";
	s << "basis : \n" << p.basis << "\n";
	return s;
}
